package com.cms.jy;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cms.jy.draft.constant.*;
import com.cms.jy.draft.entity.*;
import com.cms.jy.draft.util.AddUtil;
import com.cms.jy.utils.LyricFenjingUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
@Slf4j
public class GenTopicByLocal {
    public static final String TEMPLATE_PATH = "template/c9a670dd-59d5-4b0c-b8a1-33d69a9c4a3c";
    public static void main(String[] args) throws Exception {
        GenTopicByLocal.generate("C:\\Users\\Administrator\\Videos\\c9a670dd-59d5-4b0c-b8a1-33d69a9c4a3c\\1.srt",
                "C:\\Users\\Administrator\\Videos\\c9a670dd-59d5-4b0c-b8a1-33d69a9c4a3c\\1.mp3");
    }

    public static void generate(String srtPath, String audioPath) throws Exception {
        // 1. 创建草稿（基于模板）
        String draftPath = AddUtil.createDraftFromTemplate(Config.OUTPUT_BASE_PATH, TEMPLATE_PATH);
        System.out.println("1. 草稿创建完成，路径: " + draftPath);

        // 2. 读取草稿内容
        DraftContent draftContent = AddUtil.readDraftContentFromTemplate(TEMPLATE_PATH);
        System.out.println("2. 草稿内容对象读取完成");

        // 在适当的位置调用该方法
        removeEmptyPathMaterials(draftContent);

        // 3. 添加字幕的视频
        long audioDuration = AddUtil.getAudioDuration(audioPath);
        List<Map<String, Object>> srt = addTextFromSrtFile(draftContent, srtPath, audioDuration);
        System.out.println("3. 添加视频完成");

        // 4.添加背景音乐以及翻页音频特效
        long fanyeStarts = (long) srt.stream().filter(map -> map.get("text").toString().contains("今日主题")).findFirst().get().get("end");
        long fanyeStarts2 = (long) srt.stream().filter(map -> map.get("text").toString().contains("今日主题")).findFirst().get().get("start");
        AddUtil.addAudio(draftContent, Config.RES_PATH + "\\tpl\\music\\bg_topic2.mp3", 0, audioDuration, 0.0, "bg-audio");
        AddUtil.addAudio(draftContent, Config.RES_PATH + "\\tpl\\music\\fanye_topic.mp3",
                fanyeStarts,
                AddUtil.timeCodeToMillis("00:00:01:26", 30), 0.0, "fanye-adui");
        // 今日主题背景视频
        AddUtil.addVideo(draftContent, Config.RES_PATH + "\\tpl\\music\\bg-jrzt.mp4", "bg-jrzt",
                fanyeStarts2, AddUtil.timeCodeToMillis("00:00:02:48", 30),AddUtil.timeCodeToMillis("00:00:02:48", 30),
                null, null, null, 0, 0, 1.0, 1.0, 0.0, 1.0,
                null, 0.0, null);
        // 开头视频
        AddUtil.addVideo(draftContent, Config.RES_PATH + "\\tpl\\music\\bg-jrzt-s.mp4", "bg-jrzt",
                0, fanyeStarts2,fanyeStarts2,
                null, null, null, 0, 0, 1.0, 1.0, 0.0, 1.0,
                null, 0.36, null);
        // 结尾视频
        AddUtil.addVideo(draftContent, Config.RES_PATH + "\\tpl\\music\\bg-jrzt-e.mp4", "bg-jrzt",
                audioDuration - AddUtil.timeCodeToMillis("00:00:08:05", 30),
                AddUtil.timeCodeToMillis("00:00:09:04", 30),AddUtil.timeCodeToMillis("00:00:09:04", 30),
                null, null, null, 0, 0, 1.0, 1.0, 0.0, 1.0,
                null, 0.36, null);
        System.out.println("4. 添加背景音乐以及翻页音频特效");

        // 5. 添加特效 噪点
        AddUtil.addEffect(draftContent, VideoSceneEffectType.YING_MU_ZAO_DIAN,0, fanyeStarts2);
        long contentStart = fanyeStarts2 + AddUtil.timeCodeToMillis("00:00:01:26", 30);
        AddUtil.addEffect(draftContent, VideoSceneEffectType.YING_MU_ZAO_DIAN, contentStart, audioDuration - contentStart);
        AddUtil.addEffect(draftContent, VideoSceneEffectType2.BI_MU_II,audioDuration - 3000000, 3000000);
        System.out.println("5. 特效添加完成");



        // 9. 保存草稿
        AddUtil.saveDraft(draftContent, draftPath);
        System.out.println("9. 草稿保存完成");
    }

    /**
     * 简化版本：添加SRT字幕到草稿
     *
     * @param filePath SRT字幕文件
     * @return 最后一个添加的文本的草稿ID
     * @throws Exception IO异常
     */
    public static List<Map<String, Object>> addTextFromSrtFile(DraftContent draftContent, String filePath, long audioDuration) throws Exception {
        try {
            // 指定UTF-8编码读取文件
            String content = new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8);
            // 清理数据
            // content = content.trim().replaceAll("[^\\x20-\\x7e\\x{4e00}-\\x{9fff}]", "");
            return  addTextFromSrt(draftContent, content, audioDuration);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 解析SRT字幕文件内容并添加到草稿
     *
     * @param srtContent SRT字幕内容
     * @return 最后一个添加的文本的草稿ID
     * @throws Exception IO异常
     */
    public static List<Map<String, Object>> addTextFromSrt(DraftContent draftContent, String srtContent, long audioDuration) throws Exception {
        String[] lines = srtContent.split("\n");
        List<Map<String, Object>> srt = new ArrayList<>();


        JSONObject jsonObject = JSON.parseObject("{\"fenjins\":[{\"keywords\":\"月光,屋檐\",\"start\":\"00:00:00,066\",\"end\":\"00:00:02,700\"},{\"keywords\":\"山川,一个人\",\"start\":\"00:00:03,766\",\"end\":\"00:00:06,366\"},{\"keywords\":\"群山,少年,山路\",\"start\":\"00:00:07,466\",\"end\":\"00:00:13,866\"},{\"keywords\":\"生命\",\"start\":\"00:00:15,100\",\"end\":\"00:00:17,900\"},{\"keywords\":\"一个人,不勇敢\",\"start\":\"00:00:18,700\",\"end\":\"00:00:21,600\"},{\"keywords\":\"繁星,人间\",\"start\":\"00:00:22,466\",\"end\":\"00:00:29,166\"},{\"keywords\":\"绿荫,高山,小路\",\"start\":\"00:00:31,666\",\"end\":\"00:00:35,400\"},{\"keywords\":\"河水,衣衫\",\"start\":\"00:00:35,600\",\"end\":\"00:00:38,400\"},{\"keywords\":\"瘦弱的肩\",\"start\":\"00:00:39,133\",\"end\":\"00:00:40,900\"},{\"keywords\":\"掌心,茧\",\"start\":\"00:00:40,900\",\"end\":\"00:00:42,800\"},{\"keywords\":\"心酸\",\"start\":\"00:00:43,133\",\"end\":\"00:00:45,933\"},{\"keywords\":\"鞋子,衣服\",\"start\":\"00:00:46,866\",\"end\":\"00:00:50,366\"},{\"keywords\":\"麻花包,饭\",\"start\":\"00:00:50,600\",\"end\":\"00:00:54,100\"},{\"keywords\":\"汗水,石卷,答案\",\"start\":\"00:00:54,200\",\"end\":\"00:00:57,900\"},{\"keywords\":\"烛光,眉眼\",\"start\":\"00:00:58,100\",\"end\":\"00:01:00,800\"},{\"keywords\":\"月光,屋檐\",\"start\":\"00:01:01,933\",\"end\":\"00:01:04,400\"},{\"keywords\":\"山川,一个人\",\"start\":\"00:01:05,533\",\"end\":\"00:01:08,466\"},{\"keywords\":\"群山,少年,山路\",\"start\":\"00:01:09,333\",\"end\":\"00:01:15,933\"},{\"keywords\":\"身影,不勇敢\",\"start\":\"00:01:16,800\",\"end\":\"00:01:23,500\"},{\"keywords\":\"繁星,人间\",\"start\":\"00:01:24,666\",\"end\":\"00:01:30,900\"},{\"keywords\":\"绿荫,高山,山路\",\"start\":\"00:01:48,600\",\"end\":\"00:01:52,266\"},{\"keywords\":\"河水,衣衫\",\"start\":\"00:01:52,500\",\"end\":\"00:01:55,300\"},{\"keywords\":\"瘦弱的肩\",\"start\":\"00:01:56,000\",\"end\":\"00:01:57,766\"},{\"keywords\":\"掌心,茧\",\"start\":\"00:01:57,766\",\"end\":\"00:01:59,700\"},{\"keywords\":\"心酸\",\"start\":\"00:02:00,000\",\"end\":\"00:02:02,733\"},{\"keywords\":\"鞋子,缝补\",\"start\":\"00:02:03,766\",\"end\":\"00:02:07,300\"},{\"keywords\":\"巴黎,帆\",\"start\":\"00:02:07,500\",\"end\":\"00:02:11,000\"},{\"keywords\":\"汗水,石卷,答案\",\"start\":\"00:02:11,100\",\"end\":\"00:02:14,700\"},{\"keywords\":\"烛光,眉眼\",\"start\":\"00:02:14,966\",\"end\":\"00:02:17,700\"},{\"keywords\":\"月光,屋檐\",\"start\":\"00:02:18,866\",\"end\":\"00:02:21,300\"},{\"keywords\":\"山川,一个人\",\"start\":\"00:02:22,400\",\"end\":\"00:02:25,333\"},{\"keywords\":\"群山,少年\",\"start\":\"00:02:26,200\",\"end\":\"00:02:29,566\"},{\"keywords\":\"山路\",\"start\":\"00:02:29,566\",\"end\":\"00:02:32,566\"},{\"keywords\":\"身影\",\"start\":\"00:02:33,800\",\"end\":\"00:02:36,666\"},{\"keywords\":\"勇敢\",\"start\":\"00:02:37,500\",\"end\":\"00:02:40,366\"},{\"keywords\":\"繁星,人间\",\"start\":\"00:02:41,133\",\"end\":\"00:02:47,800\"}]} \n");
        JSONArray fenjin = jsonObject.getJSONArray("fenjins");
        //JSONArray fenjin = LyricFenjingUtil.generateFenjing(srtContent);
        // 处理分镜数据
        List<JSONObject> fenjins = LyricFenjingUtil.processFenjins(fenjin);
        long preStart = 0, preEnd = 0;
        List<String> usedVideoUrls = new ArrayList<>();
        for (JSONObject fj : fenjins) {
            // 解析正在时间
            long startTime = parseSrtTime(fj.getString("start"));
            // 解析结束时间
            long endTime = parseSrtTime(fj.getString("end"));
            long duration = endTime - preStart;
            preEnd = endTime;
            String videoUrl = getVideoUrl(fj.getString("keywords"), usedVideoUrls);
            if (usedVideoUrls.contains(videoUrl)) {
                for (int attempt = 0; attempt < 3; attempt++) {
                    videoUrl = getVideoUrl(fj.getString("keywords"), usedVideoUrls);
                    // 如果URL未使用过，则返回该URL
                    if (!usedVideoUrls.contains(videoUrl)) {
                        usedVideoUrls.add(videoUrl); // 标记为已使用
                        break;
                    }
                    log.warn("第{}次尝试获取视频URL，但URL已使用: {}", attempt + 1, videoUrl);
                }
            } else {
                usedVideoUrls.add(videoUrl);
            }
            log.info("添加分镜视频素材...,开始：{}，结束：{}, {}", startTime, endTime, videoUrl);
            try {
                AddUtil.addVideo(draftContent, videoUrl, "video",
                        preStart, duration,duration,
                        null,null, VideoTransitions.mo_hu.setDuration( 1.3),
                        0, 0, 1.0, 1.0, 0.0, 1.0, "", 1.0, null);
                preStart = endTime;
            } catch (Exception e) {
                throw new Exception(e);
            }
        };

        // 添加字幕
        for (int i = 0; i < lines.length; i++) {
            String line = lines[i].trim();
            // 检查是否为字幕序号行
            if (line.matches("\\d+") && i + 1 < lines.length) {
                // 下一行应该是时间码
                String timeLine = lines[i + 1].trim();
                if (timeLine.contains("-->")) {
                    String[] times = timeLine.split("-->");
                    if (times.length == 2 && i + 2 < lines.length) {
                        // 解析正在时间
                        long startTime = parseSrtTime(times[0].trim());
                        // 解析结束时间
                        long endTime = parseSrtTime(times[1].trim());

                        // 获取字幕文本（可能跨越多行）
                        StringBuilder textBuilder = new StringBuilder();
                        int j = i + 2;
                        while (j < lines.length && !lines[j].trim().isEmpty() && !lines[j].trim().matches("\\d+")) {
                            if (textBuilder.length() > 0) {
                                textBuilder.append("\n");
                            }
                            textBuilder.append(lines[j].trim());
                            j++;
                        }
                        String text = textBuilder.toString();

                        Map<String, Object> srtItem = new HashMap<>();
                        srtItem.put("text", text);
                        srtItem.put("start", startTime);
                        srtItem.put("end", endTime);
                        srt.add(srtItem);
                        i = j - 1; // 更新索引位置
                    }
                }
            }
        }
        return srt;
    }


    private static String getVideoUrl(String keywords, List<String> usedVideoUrls) {
        String dirVideo = Config.RES_PATH + "\\视频\\横屏";
        File[] files = new File(dirVideo).listFiles();

        // 如果目录为空或无法访问，返回默认视频
        if (files == null || files.length == 0) {
            return dirVideo + "\\海水-夕阳.webm";
        }

        // 如果keywords为空，从所有文件中随机选择一个
        if (keywords == null || keywords.trim().isEmpty()) {
            Random random = new Random();
            File randomFile = files[random.nextInt(files.length)];
            return dirVideo + "\\" + randomFile.getName();
        }

        // 收集所有匹配关键词的视频文件
        List<File> matchedFiles = new ArrayList<>();
        String[] keywordArray = keywords.split("[,，]"); // 支持中英文逗号分隔
        File bestMatchFile = null;
        int maxMatches = 0;
        // 遍历所有文件，计算每个文件匹配的关键字数量
        for (File file : files) {
            int matchCount = 0;

            if ( String.join(",", usedVideoUrls).contains(file.getName())) {
                continue;
            }

            // 计算当前文件匹配的关键字数量
            for (String keyword : keywordArray) {
                keyword = keyword.trim();
                if (!keyword.isEmpty() && file.getName().contains(keyword)) {
                    matchCount++;
                }
            }

            // 如果当前文件匹配度更高，则更新最佳匹配
            if (matchCount > maxMatches) {
                maxMatches = matchCount;
                bestMatchFile = file;
            }
        }

        // 如果有匹配的文件，返回最佳匹配文件
        if (bestMatchFile != null) {
            return dirVideo + "\\" + bestMatchFile.getName();
        }

        // 如果没有匹配的文件，从所有文件中随机选择一个
        Random random = new Random();
        File randomFile = files[random.nextInt(files.length)];
        return dirVideo + "\\" + randomFile.getName();
    }

    /**
     * 解析SRT时间格式为微秒
     *
     * @param timeStr SRT时间字符串，格式为 HH:mm:ss,mmm
     * @return 时间（微秒）
     */
    private static long parseSrtTime(String timeStr) {
        String[] parts = timeStr.split("[:,]");
        if (parts.length == 4) {
            int hours = Integer.parseInt(parts[0]);
            int minutes = Integer.parseInt(parts[1]);
            int seconds = Integer.parseInt(parts[2]);
            int milliseconds = Integer.parseInt(parts[3]);
            // 先计算总毫秒数，然后乘以1000转换为微秒
            long totalMilliseconds = (hours * 3600 + minutes * 60 + seconds) * 1000L + milliseconds;
            return totalMilliseconds * 1000L; // 转换为微秒
        }
        return 0;
    }
    
    /**
     * 删除materials中path为空的videos和audios对象，并删除引用这些对象ID的segments配置
     * 
     * @param draftContent 草稿内容对象
     */
    public static void removeEmptyPathMaterials(DraftContent draftContent) {
        if (draftContent == null || draftContent.getMaterials() == null) {
            return;
        }
        
        Materials materials = draftContent.getMaterials();
        List<String> removedVideoIds = new ArrayList<>();
        List<String> removedAudioIds = new ArrayList<>();
        
        // 删除path为空的videos
        if (materials.getVideos() != null) {
            Iterator<Video> videoIterator = materials.getVideos().iterator();
            while (videoIterator.hasNext()) {
                Video video = videoIterator.next();
                if (video != null && (video.getPath() == null || video.getPath().isEmpty())) {
                    removedVideoIds.add(video.getId());
                    videoIterator.remove();
                } else {
                    removedVideoIds.add(video.getId());
                    videoIterator.remove();
                }
            }
        }
        
        // 删除path为空的audios
        if (materials.getAudios() != null) {
            Iterator<Audio> audioIterator = materials.getAudios().iterator();
            while (audioIterator.hasNext()) {
                Audio audio = audioIterator.next();
                if (audio != null && (audio.getPath() == null || audio.getPath().isEmpty())) {
                    removedAudioIds.add(audio.getId());
                    audioIterator.remove();
                }
            }
        }
        
        // 删除引用这些视频ID的segments
        removeSegmentsByMaterialIds(draftContent, removedVideoIds);
        
        // 删除引用这些音频ID的segments
        removeSegmentsByMaterialIds(draftContent, removedAudioIds);
    }

    /**
     *
     * @param draftContent 草稿内容对象
     * @param materialIds 要删除的材料ID列表
     */
    private static void removeSegmentsByMaterialIds(DraftContent draftContent, List<String> materialIds) {
        if (draftContent.getTracks() == null || materialIds == null || materialIds.isEmpty()) {
            return;
        }

        Iterator<Track> trackIterator = draftContent.getTracks().iterator();
        while (trackIterator.hasNext()) {
            Track track = trackIterator.next();
            if (track.getSegments() != null) {
                Iterator<Segment> segmentIterator = track.getSegments().iterator();
                while (segmentIterator.hasNext()) {
                    Segment segment = segmentIterator.next();
                    if (segment != null && materialIds.contains(segment.getMaterial_id())) {
                        segmentIterator.remove();
                    }
                }
            }
            if (track.getSegments() != null && track.getSegments().isEmpty()) {
                trackIterator.remove(); // 使用迭代器安全删除
            }
        }
    }
}
